package com.wbk.lotterysystemuserservice.controller.biz;

import cn.hutool.crypto.SecureUtil;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.wbk.lotterysystemuserservice.commons.bo.UserLoginBO;
import com.wbk.lotterysystemuserservice.commons.bo.UserRegisterBO;
import com.wbk.lotterysystemuserservice.commons.bo.UserResetBO;
import com.wbk.lotterysystemuserservice.commons.dto.UserLoginDTO;
import com.wbk.lotterysystemuserservice.entity.User;
import com.wbk.lotterysystemuserservice.entity.UserExt;
import com.wbk.lotterysystemuserservice.service.UserExtInfoService;
import com.wbk.lotterysystemuserservice.service.UserInfoService;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import result.Result;


import java.util.Map;

import static tools.JWTUtil.*;

@Component
public class UserInfoBiz {

    @Autowired
    UserInfoService userInfoService;

    @Autowired
    UserExtInfoService userExtInfoService;

    public Result<UserLoginDTO> login(UserLoginBO userLoginBO) {
        User userByUsername = userInfoService.getUserByUsername(userLoginBO.getUsername());
        if (userByUsername == null) {
            return new Result<>(100, "用户不存在", null);
        }
        Map<String, Object> map = userInfoService.loginUserLock(userLoginBO.getUsername());
        if ((boolean) map.get("flag")) {
            Long expire = (Long) map.get("expire");
            String reason = (String) map.get("reason");
            return new Result<>(999, "用户已被封禁，无法登陆！！！\n封禁原因：" + reason + ".\n剩余时间:" + expire + "分钟", null);
        }
        User user = userInfoService.getUserByUsernameAndPassword(userLoginBO.getUsername(), userLoginBO.getPassword());
        if (user == null) {
            String result = userInfoService.loginError(userLoginBO.getUsername());
            return new Result<>(100, "用户名和密码不匹配\n" + result, null);
        }
        UserExt userExt = userExtInfoService.getUserExt(user.getUserNo());
        UserLoginDTO userLoginDTO = new UserLoginDTO();
        BeanUtils.copyProperties(user, userLoginDTO);
        BeanUtils.copyProperties(userExt, userLoginDTO);
        String token = create(user.getUserNo());
        userLoginDTO.setToken(token);
        return new Result<>(200, "登录成功", userLoginDTO);
    }

    @Transactional(propagation = Propagation.REQUIRED)
    public Result<UserLoginDTO> register(UserRegisterBO userRegisterBO) {
        User userByUsername = userInfoService.getUserByUsername(userRegisterBO.getUsername());
        if (userByUsername != null) {
            return new Result<>(100, "该用户名已被使用", null);
        }
        if (!userRegisterBO.getPassword().equals(userRegisterBO.getRePassword())) {
            return new Result<>(100, "两次密码不一致", null);
        }
        boolean flag = userInfoService.codeExpire(userRegisterBO.getEmail(), userRegisterBO.getCode());
        if (!flag) {
            return new Result<>(100, "验证码错误或过期", null);
        }
        User userByEmail = userInfoService.getUserByEmail(userRegisterBO.getEmail());
        if (userByEmail != null) {
            return new Result<>(100, "该邮箱已被注册", null);
        }
        User userByMobile = userInfoService.getUserByMobile(userRegisterBO.getMobile());
        if (userByMobile != null) {
            return new Result<>(100, "该手机号已被注册", null);
        }
        User user = userInfoService.save(userRegisterBO);
        UserExt userExt = userExtInfoService.save(user);
        UserLoginDTO userLoginDTO = new UserLoginDTO();
        BeanUtils.copyProperties(user, userLoginDTO);
        BeanUtils.copyProperties(userExt, userLoginDTO);
        userLoginDTO.setToken(create(user.getUserNo()));
        return new Result<>(200, "注册成功", userLoginDTO);
    }

    @Transactional(propagation = Propagation.REQUIRED)
    public Result reset(UserResetBO userResetBO) {
        if (!userResetBO.getPassword().equals(userResetBO.getRePassword())) {
            return new Result(100, "两次密码不一致", null);
        }
        boolean flag = userInfoService.codeExpire(userResetBO.getEmail(), userResetBO.getCode());
        if (!flag) {
            return new Result(100, "验证码错误或过期", null);
        }
        User user = userInfoService.getUserByEmail(userResetBO.getEmail());
        if (user == null) {
            return new Result(100, "没找到用户信息，请重试", null);
        }
        user.setPassword(SecureUtil.md5(userResetBO.getPassword()));
        int result = userInfoService.reset(user);
        return result == 1 ? new Result(200, "修改成功", null) : new Result(100, "修改失败", null);
    }

    public Result<UserLoginDTO> token(String token) {
        if (StringUtils.isEmpty(token)) {
            return new Result<>(100, "没有token,请登录", null);
        }
        DecodedJWT jwt = null;
        try {
            jwt = verify(token);
        } catch (Exception e) {
            return new Result<>(100, "token异常或已过期", null);
        }
        if (jwt == null) {
            return new Result<>(100, "token异常或已过期", null);
        }
        Long userNo = getUserNo(jwt);
        if (userNo <= 0) {
            return new Result<>(100, "token异常或已过期", null);
        }
        User user = userInfoService.getUserByUserNo(userNo);
        if (user == null) {
            return new Result<>(100, "没找到用户信息，请重试", null);
        }
        Map<String, Object> map = userInfoService.loginUserLock(user.getUsername());
        if ((boolean) map.get("flag")) {
            Long expire = (Long) map.get("expire");
            String reason = (String) map.get("reason");
            return new Result<>(999, "用户已被封禁，无法登陆！！！\n封禁原因：" + reason + ".\n剩余时间:" + expire + "分钟", null);
        }
        UserExt userExt = userExtInfoService.getUserExt(userNo);
        if (userExt == null) {
            return new Result<>(100, "没找到用户信息，请重试", null);
        }
        UserLoginDTO userLoginDTO = new UserLoginDTO();
        BeanUtils.copyProperties(user, userLoginDTO);
        BeanUtils.copyProperties(userExt, userLoginDTO);
        userLoginDTO.setToken(token);
        return new Result<>(200, "token正常", userLoginDTO);
    }


}
